﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NUnit.Framework;
using Bastanteo.Persistencia;
using Bastanteo.Domain;
using Bastanteo.Persistencia.NH;

namespace Bastanteo.Tests
{
    [TestFixture]
    public class Test_UsuarioDAO
    {
        // DAOs a utilizar durante las pruebas
        private IRolDAO rolDAO = null;
        //private IInstrumentoDAO instrumentoDAO = null;
        private IUsuarioDAO usuarioDAO = null;
        // Variables de soporte para las pruebas
        private Rol rol1 = null;
        private Rol rol2 = null;
        //private Instrumento instrumento1 = null;
        //private Instrumento instrumento2 = null;
        private int codigoUsuario = 0;

        [TestFixtureSetUp]
        public void PrepararPruebas()
        {
            // 1. Definimos la implementación de DAO a probar (ADO / NH / EF)
            rolDAO = new Persistencia.ADO.RolDAO();
            //instrumentoDAO = new Persistencia.EF.InstrumentoDAO();
            usuarioDAO = new Persistencia.ADO.UsuarioDAO();
            // 2. Eliminamos todas las salas en BD antes de las pruebas
            foreach (Usuario usuario in usuarioDAO.Listar())
                usuarioDAO.Eliminar(usuario);
            // 3. Creamos objetos dependientes necesarios
            rol1 = rolDAO.Crear(new Rol() { RolDescripcion = "Administracion" });
            rol2 = rolDAO.Crear(new Rol() { RolDescripcion = "Operador" });
        }

        [Test]
        public void Test1_Crear()
        {
            // 1. Clase a probar: SalaDAO
            Assert.IsNotNull(usuarioDAO);
            // 2. Declaramos e instanciamos la entidad de dominio
            Usuario usuarioACrear = new Usuario()
            {
                Codigo = "RHUAMANI",
                usuario = "Raul Huamani",
                Password = "400",
                Rol = rol1,

            };
            // 3. Declaramos la entidad que contendrá el resultado
            Usuario usuarioCreado = null;
            // 4. Probamos que no ocurra error al ejecutar el método
            Assert.DoesNotThrow(delegate
            {
                // 5. Ejecutamos el método a probar
                usuarioCreado = usuarioDAO.Crear(usuarioACrear);
                codigoUsuario = usuarioCreado.UsuarioId;
            });
            // Probamos que la entidad resultante no sea nula
            Assert.IsNotNull(usuarioCreado);
            // Probamos que el código generado sea mayor a 0
            Assert.Greater(usuarioCreado.UsuarioId, 0);
            // Probamos que el nombre registrado es igual al solicitado con la entidad
            Assert.AreEqual(usuarioCreado.Codigo, usuarioACrear.Codigo);
            // Probamos que la característica registrada es igual a la solicitada con la entidad
            Assert.AreEqual(usuarioCreado.usuario, usuarioACrear.usuario);

        }
        [Test]
        public void Test2_Obtener()
        {
            // 1. Clase a probar: LocalDAO
            Assert.IsNotNull(usuarioDAO);
            // 2. Definimos los datos para la prueba
            int codigo = codigoUsuario;
            // 3. Declaramos la entidad que contendrá el resultado
            Usuario usuarioObtenido = null;
            // 4. Probamos que no ocurra error al ejecutar el método
            Assert.DoesNotThrow(delegate
            {
                // 5. Ejecutamos el método a probar
                usuarioObtenido = usuarioDAO.Obtener(codigo);
            });
            // Probamos que la entidad resultante no sea nula
            Assert.IsNotNull(usuarioObtenido);
            Assert.AreEqual(usuarioObtenido.UsuarioId, codigo);
            Assert.IsNotNullOrEmpty(usuarioObtenido.usuario);
            Assert.IsNotNullOrEmpty(usuarioObtenido.Password);
        }
        [Test]
        public void Test3_Modificar()
        {
            // 1. Clase a probar: LocalDAO
            Assert.IsNotNull(usuarioDAO);
            // 2. Declaramos e instanciamos la entidad de dominio
            Usuario usuarioAModificar = usuarioDAO.Obtener(codigoUsuario);
            // a. Solicitamos cambios en las propiedades escalares
            usuarioAModificar.usuario = "Juan Perez";
            usuarioAModificar.Password = "Prueba2";
            // b. Solicitamos cambios en un objeto anidado
            usuarioAModificar.Rol = rol2;
            // 3. Declaramos la entidad que contendrá el resultado
            Usuario usuarioModificado = null;
            // 4. Probamos que no ocurra error al ejecutar el método
            Assert.DoesNotThrow(delegate
            {
                // 5. Ejecutamos el método a probar
                usuarioModificado = usuarioDAO.Modificar(usuarioAModificar);
            });
            // Probamos que la entidad resultante no sea nula
            Assert.IsNotNull(usuarioModificado);
            // Probamos que el código generado sea mayor a 0
            Assert.AreEqual(usuarioModificado.UsuarioId, codigoUsuario);
            // Probamos que el nombre registrado es igual al solicitado con la entidad
            Assert.AreEqual(usuarioModificado.usuario, usuarioAModificar.usuario);
            // Probamos que la característica registrada es igual a la solicitada con la entidad
            Assert.AreEqual(usuarioModificado.Password, usuarioAModificar.Password);
        }
        [Test]
        public void Test4_Eliminar()
        {
            // 1. Clase a probar: LocalDAO
            Assert.IsNotNull(usuarioDAO);
            // 2. Definimos la entidad que contendrá el resultado
            Usuario usuarioExistente = usuarioDAO.Obtener(codigoUsuario);
            // 3. Probamos que no ocurra error al ejecutar el método
            Assert.DoesNotThrow(delegate
            {
                // 5. Ejecutamos el método a probar
                usuarioDAO.Eliminar(usuarioExistente);
            });
            // Probamos que la entidad ya no existe
            Assert.IsNull(usuarioDAO.Obtener(codigoUsuario));
        }
        [Test]
        public void Test5_ListarTodos()
        {
            // 1. Clase a probar: LocalDAO
            Assert.IsNotNull(usuarioDAO);
            // 2. Declaramos la entidad que contendrá el resultado
            ICollection<Usuario> usuariosEncontrados = null;
            // 3. Probamos que no ocurra error al ejecutar el método
            usuarioDAO.Crear(new Usuario() { Codigo = "USER01", usuario = "Prueba01", Password = "1234", Rol = rol1});
            usuarioDAO.Crear(new Usuario() { Codigo = "USER02", usuario = "Prueba02", Password = "1234", Rol = rol2});
            Assert.DoesNotThrow(delegate
            {
                // 5. Ejecutamos el método a probar
                usuariosEncontrados = usuarioDAO.Listar();
            });
            // Probamos que la entidad resultante no sea nula
            Assert.IsNotNull(usuariosEncontrados);
            // Probamos que la cantidad de locales encontrados sea 2
            Assert.AreEqual(usuariosEncontrados.Count, 2);
            // Probamos que cada local contenga la cadena de búsqueda en su nombre
            foreach (Usuario usuarioEncontrado in usuariosEncontrados)
            {
                Assert.IsNotNull(usuarioEncontrado);
                Assert.IsInstanceOf(typeof(Usuario), usuarioEncontrado);
            }
        }
        [Test]
        public void Test6_ListarXBusqueda()
        {
            // 1. Clase a probar: LocalDAO
            Assert.IsNotNull(usuarioDAO);
            // 2. Definimos los datos para la prueba
            string nombre = "USER01"; // Rock *
            // 3. Declaramos la entidad que contendrá el resultado
            ICollection<Usuario> usuariosEncontrados = null;
            // 4. Probamos que no ocurra error al ejecutar el método
            Assert.DoesNotThrow(delegate
            {
                // 5. Ejecutamos el método a probar
                usuariosEncontrados = usuarioDAO.ListarXBusqueda(nombre, null, null);
            });
            // Probamos que la entidad resultante no sea nula
            Assert.IsNotNull(usuariosEncontrados);
            // Probamos que la cantidad de locales encontrados sea 2
            Assert.AreEqual(usuariosEncontrados.Count, 1);
            // Probamos que cada local contenga la cadena de búsqueda en su nombre
            foreach (Usuario usuarioEncontrado in usuariosEncontrados)
            {
                Assert.IsTrue(usuarioEncontrado.Codigo.Contains(nombre));
            }
        }

        [TestFixtureTearDown]
        public void TerminarPruebas()
        {
            foreach (Usuario usuario in usuarioDAO.Listar())
                usuarioDAO.Eliminar(usuario);
            rolDAO.Eliminar(rol2);
            rolDAO.Eliminar(rol1);
            NHibernateHelper.CerrarFabrica();
        }
    }
}